package com.hzhc.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzhc.entity.CntrYard;
import com.hzhc.enumBean.ResultUtilCodeEnum;
import com.hzhc.mapper.CntrYardMapper;
import com.hzhc.service.CntrYardService;
import com.hzhc.utils.ResultUtil;
import com.hzhc.vo.CntrYardVo;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 场箱位 服务实现类
 * </p>
 *
 * @author 功不唐捐
 * @since 2024-05-23
 */
@Service
@RequiredArgsConstructor
public class CntrYardServiceImpl extends ServiceImpl<CntrYardMapper, CntrYard> implements CntrYardService {

    @Override
    public List<CntrYardVo> getCntrYardList(Page<CntrYardVo> page, CntrYardVo vo) {


        IPage<CntrYardVo> iPage = baseMapper.getCntrYardList(page,vo);
        return iPage.getRecords();
    }

    private static final String[] COLOR = { "#8aec61", "#fdee38", "#fe6161", "#3E93DA", "#c300ff" };

    @Override
    public ResultUtil<T> addCntrYard(CntrYard yard) {
        int layer = Integer.parseInt(yard.getLayer());
        if ((layer > 5) || (layer < 1)) {
            return ResultUtil.build(ResultUtilCodeEnum.LAYER_ERROR);
        }
        // 查询要插入的父箱区是否存在
        List<CntrYard> cntrYardList = baseMapper.selectList(
                Wrappers.<CntrYard>lambdaQuery().eq(CntrYard::getArea, yard.getArea()).isNull(CntrYard::getPid));
        if (!cntrYardList.isEmpty()) {
            return ResultUtil.build(ResultUtilCodeEnum.AREA_ERROR);
        }

        // 如果不存在，先创建子箱区数组 并获得起始和结束位置的值
        List<CntrYard> cntrYardChildList = new ArrayList<>();
        int startBay = Integer.parseInt(yard.getStartBay());
        int endBay = Integer.parseInt(yard.getEndBay());
        int startRow = 1;
        int endRow = 1;
        // 由于可能是字母，需要转义一下
        if (isLetterDigit(yard.getStartRow())) {
            // 字母
            startRow = letterToNumber(yard.getStartRow());
        } else {
            // 数字
            startRow = Integer.parseInt(yard.getStartRow());
        }
        if (isLetterDigit(yard.getEndRow())) {
            // 字母
            endRow = letterToNumber(yard.getEndRow());
        } else {
            // 数字
            endRow = Integer.parseInt(yard.getEndRow());
        }
        // 将int类型转化为String 并为个位数补0
        List<String> rowArray = new ArrayList<>();
        for (int r = startRow; r <= endRow; r++) {
            if (r < 10) {
                rowArray.add("0" + r);
            } else {
                rowArray.add(r + "");
            }
        }

        // 将String数组转化为Json数据
        JSONArray arr = JSON.parseArray(JSON.toJSONString(rowArray));
        // 将json数据赋值给cntrYard准备显示到前台
        yard.setRowArray(arr.toString());
        // 根据层数拼接颜色字符串json数据
        StringBuilder layerColor = new StringBuilder("[");
        for (int i = 0; i < Integer.parseInt(yard.getLayer()); i++) {
            layerColor.append('"').append(COLOR[i]).append('"').append(',');
        }
        layerColor = new StringBuilder(layerColor.substring(0, layerColor.length() - 1));
        layerColor.append("]");
        yard.setLayerColor(layerColor.toString());
        // 将已经被赋值的主箱区存入数据库
        yard.setCreateTime(LocalDateTime.now());
        baseMapper.insert(yard);
        // 根据主箱区信息（起始位置和终止位置）生成子箱区
        for (int i = startBay; i <= endBay; i++) {
            CntrYard cntrYardChild = new CntrYard();
            String bayArea = "";
//            if(i%4!=0){
            if (i < 10) {
                bayArea = "0" + i;
            } else {
                bayArea = i + "";
            }
//            }
            if (StrUtil.isNotBlank(bayArea)) {
                cntrYardChild.setPid(yard.getId());
                cntrYardChild.setArea(yard.getArea());
                cntrYardChild.setBay(bayArea);
                cntrYardChild.setRowArray(arr.toString());
                cntrYardChild.setLayer(yard.getLayer());
                cntrYardChild.setLayerColor(layerColor.toString());
                cntrYardChildList.add(cntrYardChild);
            }
        }
        // 如果生成了子箱区就批量存入数据库
        if (!cntrYardChildList.isEmpty()) {
            saveBatch(cntrYardChildList);
        }
        return ResultUtil.ok();
    }

    @Override
    public ResultUtil<T> updateCntrYard(CntrYard yard) {
        int layer = Integer.parseInt(yard.getLayer());
        if ((layer > 5) || (layer < 1)) {
            return ResultUtil.build(ResultUtilCodeEnum.LAYER_ERROR);
        }
        // 查询要更新的父箱区是否存在
        List<CntrYard> cntrYardList = baseMapper.selectList(Wrappers.<CntrYard>lambdaQuery()
                .eq(CntrYard::getArea, yard.getArea())
                .isNull(CntrYard::getPid).eq(CntrYard::getDisable,0));

        //重复修改检测，若修改前后id一致则认为非重复修改，不一致则限制同名修改
        if (!cntrYardList.isEmpty()) {
            for (CntrYard cntrYardTmp : cntrYardList){
                boolean b = cntrYardTmp.getId().equals(yard.getId());
                if (!b){
                    return ResultUtil.build(ResultUtilCodeEnum.AREA_ERROR);

                }
            }
        }

        // 更新前先删除所有子场箱位
        List<CntrYard> cntrYards = baseMapper
                .selectList(Wrappers.<CntrYard>lambdaQuery().eq(CntrYard::getPid, yard.getId()));
        if (!cntrYards.isEmpty()) {
            QueryWrapper<CntrYard> wrapper = new QueryWrapper<CntrYard>();
            wrapper.eq("pid", yard.getId());
            baseMapper.delete(wrapper);
        }

        // 重新生成子场箱位并赋值给cntrYard
        List<CntrYard> cntrYardChildList = new ArrayList<>();
        int startBay = Integer.parseInt(yard.getStartBay());
        int endBay = Integer.parseInt(yard.getEndBay());
        int startRow = 1;
        int endRow = 1;
        if (isLetterDigit(yard.getStartRow())) {
            // 字母
            startRow = letterToNumber(yard.getStartRow());
        } else {
            // 数字
            startRow = Integer.parseInt(yard.getStartRow());
        }
        if (isLetterDigit(yard.getEndRow())) {
            // 字母
            endRow = letterToNumber(yard.getEndRow());
        } else {
            // 数字
            endRow = Integer.parseInt(yard.getEndRow());
        }

        // 拼接所有行信息并赋值给cntrYard
        List<String> rowArray = new ArrayList<>();
        for (int r = startRow; r <= endRow; r++) {
            if (r < 10) {
                rowArray.add("0" + r);
            } else {
                rowArray.add(r + "");
            }
        }
//        JSONArray arr = JSONUtil.parseArray(rowArray);
        JSONArray arr = JSON.parseArray(JSON.toJSONString(rowArray));
        yard.setRowArray(arr.toString());

        // 保存颜色信息并赋值给cntrYard
        StringBuilder layerColor = new StringBuilder("[");
        for (int i = 0; i < Integer.parseInt(yard.getLayer()); i++) {
            layerColor.append('"').append(COLOR[i]).append('"').append(',');
        }
        layerColor = new StringBuilder(layerColor.substring(0, layerColor.length() - 1));
        layerColor.append("]");
        yard.setLayerColor(layerColor.toString());

        // 开始生成子bay
        for (int i = startBay; i <= endBay; i++) {
            CntrYard cntrYardChild = new CntrYard();
            String bayArea = "";
            if (i < 10) {
                bayArea = "0" + i;
            } else {
                bayArea = i + "";
            }
            if (StrUtil.isNotBlank(bayArea)) {
                cntrYardChild.setPid(yard.getId());
                cntrYardChild.setArea(yard.getArea());
                cntrYardChild.setBay(bayArea);
                cntrYardChild.setRowArray(arr.toString());
                cntrYardChild.setLayer(yard.getLayer());
                cntrYardChild.setLayerColor(layerColor.toString());
                cntrYardChildList.add(cntrYardChild);
            }
        }
        if (!cntrYardChildList.isEmpty()) {
            saveBatch(cntrYardChildList);
        }
        yard.setUpdateTime(LocalDateTime.now());
        updateById(yard);
        return ResultUtil.ok();
    }

    @Override
    public ResultUtil<T> delCntrYard(Long id) {

        List<CntrYard> cntrYards = baseMapper.selectList(Wrappers.<CntrYard>lambdaQuery().eq(CntrYard::getPid, id));
        if (!cntrYards.isEmpty()){
            LambdaQueryWrapper<CntrYard> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CntrYard::getPid,id);
            baseMapper.delete(wrapper);
        }
        CntrYard yard = getById(id);
        yard.setDisable(1);
        boolean b = updateById(yard);
        if (b){
            return ResultUtil.ok();
        }
        return ResultUtil.fail();


    }

    @Override
    public List<CntrYardVo> getCntrYardVoJson(Page<CntrYardVo> page, CntrYardVo vo) {
        IPage<CntrYardVo> iPage = baseMapper.getCntrYardList(page, vo);
        return iPage.getRecords();
    }

    @Override
    public List<CntrYardVo> getCntrYard(CntrYardVo vo) {
        return baseMapper.getCntrYard(vo);
    }

    @Override
    public List<CntrYard> selectBayByArea(String area) {
        LambdaQueryWrapper<CntrYard> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CntrYard::getArea,area)
                .isNotNull(CntrYard::getPid)
                .eq(CntrYard::getDisable,0)
                .eq(CntrYard::getStatus,0);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public CntrYard selectRowByAreaAndBay(String area) {
        LambdaQueryWrapper<CntrYard> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CntrYard::getArea,area)
                .eq(CntrYard::getDisable,0)
                .eq(CntrYard::getStatus,0)
                .last("limit 1");

        return baseMapper.selectOne(wrapper);
    }

    @Override
    public ResultUtil<List<JSONObject>> getYardArea() {
        List<CntrYard> cntrYards = baseMapper
                .selectList(Wrappers.<CntrYard>lambdaQuery()
                        .isNull(CntrYard::getPid).orderByAsc(CntrYard::getSort)
                        .ne(CntrYard::getStartBay,0)
                        .ne(CntrYard::getStartRow,0)
                        .eq(CntrYard::getDisable,0)
                );
        if (cntrYards == null) {
            return ResultUtil.build(ResultUtilCodeEnum.DATA_NOT_EXIST);
        }
        List<JSONObject> objects = new ArrayList<>();
        for (CntrYard cntrYard : cntrYards) {
            JSONObject obj = new JSONObject();
            obj.put("area", cntrYard.getArea());
            obj.put("x", (Integer.parseInt(cntrYard.getEndBay()) - Integer.parseInt(cntrYard.getStartBay()) + 3)  / 2);
            obj.put("y", Integer.valueOf(cntrYard.getEndRow()));
            obj.put("layerColor", cntrYard.getLayerColor());
            obj.put("sort", cntrYard.getSort());
            obj.put("orderBay", cntrYard.getOrderBay());
            obj.put("orderRow", cntrYard.getOrderRow());
            objects.add(obj);
        }
        return ResultUtil.build(objects,ResultUtilCodeEnum.SUCCESS);
    }


    @Override
    public CntrYard selectRowCenBayAreaBay(String bay) {
        String[] bayStr = bay.split("-");
        String areaBay = bayStr[0] + bayStr[1];
        return baseMapper.selectRowCenBayAreaBay(areaBay);
    }

    @Override
    public CntrYard selectRowOrLayerBayArea(String area,String bay) {
        CntrYard cntrYard = baseMapper.selectOne(new QueryWrapper<CntrYard>().eq("area", area).eq("bay", bay).eq("disable", 0).last("limit 1"));
        return cntrYard;
    }

    @Override
    public List<CntrYard> selectCntrArea() {
        return baseMapper.selectList(new QueryWrapper<CntrYard>().isNull("pid").eq("disable",0).orderByAsc("sort"));
    }

    /**
     * 字母转数字
     * @param str
     * @return
     */
    private Integer letterToNumber(String str) {
        // 大写字母
        str = str.toUpperCase();
        byte[] bytes = str.getBytes();
        int num = 0;
        for (byte b : bytes) {
            num = b - 64 + 9;
        }
        return num;
    }


    /**
     * 判断是否是字母或者数字
     *
     * @param str 传入字符串
     * @return 是字母返回true，否则返回false
     */
    public boolean isLetterDigit(String str) {
        String regex = "^[a-zA-Z]+$";
        return str.matches(regex);
    }
}
